package cn.jisol.ngame.sync.frame;

import cn.jisol.ngame.proto.JNSyncMessage;
import lombok.Getter;
import lombok.Setter;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;

// 同步帧
@Getter
@Setter
public class JNSyncFrame extends TimerTask{

    //帧
    private int frame = 0;
    //同步时间
    private int frameTime = 66;

    //回调
    private JNSyncFrameCallBack callBack;

    //是否开始同步
    private boolean isStart = false;
    private Timer timer; //定时器

    //数据列表
    private CopyOnWriteArrayList<JNSyncMessage.JNFrameInfo> frameDataList = new CopyOnWriteArrayList<>();
    //当前数据
    private CopyOnWriteArrayList<JNSyncMessage.JNFrameInput> frameData = new CopyOnWriteArrayList<>();

    public JNSyncFrame(int frameTime) {
        this.frameTime = frameTime;
    }

    //绑定回调事件
    public void Bind(JNSyncFrameCallBack callBack){
        this.callBack = callBack;
    }

    //开始同步
    public void Start(){
        if (isStart) return;
        isStart = true;
        this.frame = 0;

        frameDataList = new CopyOnWriteArrayList<>();
        frameData = new CopyOnWriteArrayList<>();

        if(Objects.nonNull(this.timer)){
            this.timer.cancel();
        }

        this.timer = new Timer();
        this.timer.schedule(this , 0, frameTime);

    }

    //结束同步
    public void End(){
        isStart = false;
        if(Objects.nonNull(this.timer)){
            this.timer.cancel();
        }
    }

    @Override
    public void run() {
        JNSyncMessage.JNFrameInfo data = JNSyncMessage.JNFrameInfo.newBuilder().setIndex(this.frame++).addAllMessages(frameData).build();
        frameData = new CopyOnWriteArrayList<>();
        this.callBack.onSyncFrame(data);
        this.frameDataList.add(data);
    }

    //添加输入数据
    public void addInputs(List<JNSyncMessage.JNFrameInput> inputs){
        this.frameData.addAll(inputs);
    }

    //获取帧数据
    public JNSyncMessage.JNFrameInfos vGetFrame(Integer start, Integer end){

        //默认值
        if(Objects.isNull(start) || start == -1) start = 0;
        if((Objects.isNull(end) || end == -1) || end >= this.frameDataList.size()) end = this.frameDataList.size() - 1;

        try{
            return JNSyncMessage.JNFrameInfos.newBuilder().addAllFrames(this.frameDataList.subList(start, end)).build();
        }catch (Exception e){
            return JNSyncMessage.JNFrameInfos.newBuilder().build();
        }

    }

    public interface JNSyncFrameCallBack {
        void onSyncFrame(JNSyncMessage.JNFrameInfo syncFrame);
    }

}
